//
//  WVVPNTools.m
//  WallVPN
//
//  Created by dd on 2018/3/19.
//  Copyright © 2018年 WallVPN. All rights reserved.
//

#import "WVVPNTools.h"
#import <UIKit/UIKit.h>

#import <Security/Security.h>

@interface WVVPNTools()
@property (nonatomic, strong) VPNModel *ipsecConfig;
@property (nonatomic, strong) NEVPNManager *manager;
@property (nonatomic, copy) WVVPNToolsConnectStateBlock statusBlock;
@end


@implementation WVVPNTools

+ (instancetype)sharetoolsWithConfig:(VPNModel *)config StateBlock:(WVVPNToolsConnectStateBlock)stateBlock{
    WVVPNTools *tools = [[WVVPNTools alloc] init];
    tools.ipsecConfig  = config;
    tools.statusBlock = stateBlock;
    
    return tools;
}

- (NEVPNStatus)status{
    return self.manager.connection.status;
}

- (instancetype)init{
    if (self = [super init]) {
        
        self.manager = [NEVPNManager sharedManager];
        [self.manager loadFromPreferencesWithCompletionHandler:^(NSError * _Nullable error) {
            
        }];
        
        // 需要在loadFromPreferencesWithCompletionHandler之后调用才能获取状态
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(VPNStatusDidChangeNotification) name:NEVPNStatusDidChangeNotification object:nil];
       
    }
    return self;
}

#pragma mark VPNs
- (void)removeVPNProfile{
    [self.manager loadFromPreferencesWithCompletionHandler:^(NSError *error){
        if (!error){
            [self.manager removeFromPreferencesWithCompletionHandler:^(NSError *error){
                if(error){
                    NSLog(@"Remove error: %@", error);
                }
                else{
                    NSLog(@"removeFromPreferences");
                }
            }];
        }
    }];
}

- (void)setupIPSecWithConfig:(VPNModel *)config completion:(void (^)(NSError * error))completionHandler
{
    NSString *vpnName = [NSString stringWithFormat:@"%@%@",config.uname,config.line];
    NSString *pksName = [NSString stringWithFormat:@"%@%@",config.psk,config.line];
    
    [self createKeychainValue:config.pwd forIdentifier:vpnName];
    [self createKeychainValue:config.psk forIdentifier:pksName];
//     NEVPNProtocolIPSec *conf =(NEVPNProtocolIPSec*) self.manager.protocolConfiguration;
//    if (!conf) {
//         conf = [[NEVPNProtocolIPSec alloc] init];
//    }
    
    NEVPNProtocolIPSec *conf =[[NEVPNProtocolIPSec alloc] init];
    conf.authenticationMethod = NEVPNIKEAuthenticationMethodSharedSecret;//共享密钥方式
    conf.serverAddress = config.serverip;
    conf.username = config.uname;
    
    conf.passwordReference = [self searchKeychainCopyMatching:vpnName];//从keychain中获取密码
    conf.sharedSecretReference = [self searchKeychainCopyMatching:pksName];
    
    conf.useExtendedAuthentication = YES;
    conf.disconnectOnSleep = NO;//进入后台时是否断开VPN连接
    conf.remoteIdentifier = config.identifierName;
    
    [self.manager setProtocolConfiguration:conf];
//    [[NEVPNManager sharedManager] setOnDemandEnabled:conf];
    self.manager.localizedDescription = config.identifierName;
    
    // 设置当前配置生效  设置界面切换到别的配置时 通过设置YES可以直接使当前配置生效
    [NEVPNManager sharedManager].enabled = YES;
//    [SVProgressHUD cp_showWaitStatusWithInfo:@"正在配置VPN..." maskType:SVProgressHUDMaskTypeClear];
    [self.manager saveToPreferencesWithCompletionHandler:^(NSError * _Nullable error) {
//        if (error) {
//            [DCUserDefault saveIntValue:0 forKey:@"VPNCONFIG"];
//        }else{
//            [DCUserDefault saveIntValue:1 forKey:@"VPNCONFIG"];
//        }
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//            [SVProgressHUD dismiss];
        });
    }];
}


- (void)connect{
    [self.manager loadFromPreferencesWithCompletionHandler:^(NSError *error){
        if (!error){
            //配置IPSec  为了防止重新设置路线后重新加载
            [self setupIPSecWithConfig:self.ipsecConfig completion:^(NSError *error) {
                if (!error) {
                    
                }
            }];
            NSError *error = nil;
            [self.manager.connection startVPNTunnelAndReturnError:&error];
            if (error) {
                NSLog(@"Error-%@",error);
                if (error.code == 2) { // 为选择当前VPN的配置
                 
                }
            }
        }
    }];
}

- (void)disconnect{
    [[NEVPNManager sharedManager] loadFromPreferencesWithCompletionHandler:^(NSError *error){
        if (!error){
            [[NEVPNManager sharedManager].connection stopVPNTunnel];
        }
    }];
}

#pragma mark - VPN状态切换通知
- (void)VPNStatusDidChangeNotification
{
    NSLog(@"VPNStatusDidChangeNotification--%d",[NEVPNManager sharedManager].connection.status);
    if (self.statusBlock) {
        self.statusBlock([NEVPNManager sharedManager].connection.status);
    }
}

#pragma mark - KeyChain

static NSString * const serviceName = @"cm.WallVPN.service";

- (NSMutableDictionary *)newSearchDictionary:(NSString *)identifier {
    
    NSMutableDictionary *searchDictionary = [[NSMutableDictionary alloc] init];
    
    [searchDictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
    
    NSData *encodedIdentifier = [identifier dataUsingEncoding:NSUTF8StringEncoding];
    
    [searchDictionary setObject:encodedIdentifier forKey:(__bridge id)kSecAttrGeneric];
    
    [searchDictionary setObject:encodedIdentifier forKey:(__bridge id)kSecAttrAccount];
    
    [searchDictionary setObject:serviceName forKey:(__bridge id)kSecAttrService];
    
    return searchDictionary;
    
}

//搜索对应的keychain数据

- (NSData *)searchKeychainCopyMatching:(NSString *)identifier {
    
    NSMutableDictionary *searchDictionary = [self newSearchDictionary:identifier];

    // Add search attributes
    [searchDictionary setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
    
    // Must be persistent ref !!!!
    [searchDictionary setObject:@YES forKey:(__bridge id)kSecReturnPersistentRef];
    CFTypeRef result = NULL;
    SecItemCopyMatching((__bridge CFDictionaryRef)searchDictionary, &result);
    return (__bridge_transfer NSData *)result;
    
}

//创建对应的keychain数据

- (BOOL)createKeychainValue:(NSString *)password forIdentifier:(NSString *)identifier {
    
    NSMutableDictionary *dictionary = [self newSearchDictionary:identifier];
    OSStatus status = SecItemDelete((__bridge CFDictionaryRef)dictionary);
    NSData *passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];
    [dictionary setObject:passwordData forKey:(__bridge id)kSecValueData];
    status = SecItemAdd((__bridge CFDictionaryRef)dictionary, NULL);
        if (status == errSecSuccess) {
                return YES;
            
        }
    return NO;
    
}

@end


@implementation VPNModel


@end
